﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MediaPortal.GUI.Library;
using System.Reflection;
using System.IO;
using MediaPortal.Configuration;
using System.Diagnostics;
using MediaPortal.Dialogs;

namespace Burn4You
{
    public class Utils
    {
        private static ILog log = null;

        public static ILog Burn4YouLog
        {
            get
            {
                if (log == null)
                    log = new B4YLog();
                return log;
            }
            set
            {

                log = value;
            }
        }

        public static void CheckRequiredFiles(ILog log)
        {
            try
            {
                Assembly a = Assembly.Load("Core");
                AssemblyName an = a.GetName();
                log.Write("Core: {0}", an.Version.ToString());

                Assembly a3 = Assembly.Load("MediaPortal");
                AssemblyName an3 = a3.GetName();
                log.Write("MediaPortal: {0}", an3.Version.ToString());


                string mediaInfoVersion = "DLL Not found";
                try
                {
                    if (File.Exists(Config.GetFolder(Config.Dir.Base) + @"\MediaInfo.dll"))
                    {
                        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(Config.GetFolder(Config.Dir.Base) + @"\MediaInfo.dll");
                        mediaInfoVersion = string.Format("{0}.{1}.{2}.{3}", fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart);
                    }
                    else if (File.Exists(Config.GetFolder(Config.Dir.Plugins) + @"\windows\MediaInfo.dll"))
                    {
                        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(Config.GetFolder(Config.Dir.Plugins) + @"\windows\MediaInfo.dll");
                        mediaInfoVersion = string.Format("{0}.{1}.{2}.{3}", fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart);
                    }

                }
                catch { }

                log.Write("MediaInfo: {0} (0.7.20.0 or better recommended)", mediaInfoVersion);

                log.Write("Base Folder: {0}", Config.GetFolder(Config.Dir.Base));
                log.Write("Skin Folder: {0}", Config.GetFolder(Config.Dir.Skin));
                log.Write("Plugins Folder: {0}", Config.GetFolder(Config.Dir.Plugins));
            }
            catch (Exception ex)
            {
                log.Write("CheckRequiredFiles: {0}", ex.ToString());
            }
        }

        public static string GetApplicationVersion(Assembly a)
        {
            AssemblyName an = a.GetName();
            return an.Version.ToString();
        }

        public static string GetOSInfo()
        {
            //Get Operating system information.
            OperatingSystem os = Environment.OSVersion;
            //Get version information about the os.
            Version vs = os.Version;

            //Variable to hold our return value
            string operatingSystem = "";

            if (os.Platform == PlatformID.Win32Windows)
            {
                //This is a pre-NT version of Windows
                switch (vs.Minor)
                {
                    case 0:
                        operatingSystem = "95";
                        break;
                    case 10:
                        if (vs.Revision.ToString() == "2222A")
                            operatingSystem = "98SE";
                        else
                            operatingSystem = "98";
                        break;
                    case 90:
                        operatingSystem = "Me";
                        break;
                    default:
                        break;
                }
            }
            else if (os.Platform == PlatformID.Win32NT)
            {
                switch (vs.Major)
                {
                    case 3:
                        operatingSystem = "NT 3.51";
                        break;
                    case 4:
                        operatingSystem = "NT 4.0";
                        break;
                    case 5:
                        if (vs.Minor == 0)
                            operatingSystem = "2000";
                        else
                            operatingSystem = "XP";
                        break;
                    case 6:
                        if (vs.Minor == 0)
                            operatingSystem = "Vista";
                        else
                            operatingSystem = "7";
                        break;
                    default:
                        break;
                }
            }
            //Make sure we actually got something in our OS check
            //We don't want to just return " Service Pack 2" or " 32-bit"
            //That information is useless without the OS version.
            if (operatingSystem != "")
            {
                //Got something.  Let's prepend "Windows" and get more info.
                operatingSystem = "Windows " + operatingSystem;
                //See if there's a service pack installed.
                if (os.ServicePack != "")
                {
                    //Append it to the OS name.  i.e. "Windows XP Service Pack 3"
                    operatingSystem += " " + os.ServicePack;
                }
                //Append the OS architecture.  i.e. "Windows XP Service Pack 3 32-bit"
                operatingSystem += " " + getOSArchitecture().ToString() + "-bit";
            }
            //Return the information we've gathered.
            return operatingSystem;
        }

        public static int getOSArchitecture()
        {
            //easiest way: Just check the Size property of IntPtr.
            return IntPtr.Size * 8;
        }

        public static void DialogMsg(string title, string msg)
        {
            GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
            if (null == dlgOK)
                return;

            dlgOK.Reset();
            dlgOK.SetHeading(title);

            string[] lines = msg.Split('\n');
            Utils.Burn4YouLog.Write("lines: " + lines.Length.ToString());

            if (lines.Length == 1)
                dlgOK.SetLine(1, lines[0]);
            if (lines.Length == 2)
                dlgOK.SetLine(2, lines[1]);
            if (lines.Length == 3)
                dlgOK.SetLine(2, lines[2]);

            dlgOK.DoModal(GUIWindowManager.ActiveWindow);
        }

        public static String SelectFile()
        {
            //select a folder
            GUIDialogMenu dlgBrowse = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);

            List<ShellItem> lstItems = new List<ShellItem>();
            lstItems.Add(ShellItem.GetDeskTop());
            List<int> lstSelectedLabel = new List<int>();
            lstSelectedLabel.Add(0);

            string path = "";
            int selectedLabel = 0;
            bool available = false;
            while (true)
            {
                //show the folders in the last item
                ShellItem item = lstItems[lstItems.Count - 1];
                System.Collections.ArrayList lstSubItems = item.GetItems();

                dlgBrowse.Reset();
                dlgBrowse.SetHeading("Browse For File - " + item.DisplayName);

                int firstItem = 0;
                available = ((item.IsFileSystem || item.IsNetworkDrive) && !item.IsSystem);

                if (lstItems.Count > 1)
                {
                    dlgBrowse.Add("[<<< " + lstItems[lstItems.Count - 2].DisplayName + "]");
                    firstItem++;
                }

                List<ShellItem> lstGuiItems = new List<ShellItem>();
                foreach (object obj in lstSubItems)
                {
                    ShellItem subItem = obj as ShellItem;
                    if (subItem != null && !subItem.IsSystem)
                    {
                        lstGuiItems.Add(subItem);
                        dlgBrowse.Add(subItem.DisplayName);
                    }
                }

                selectedLabel = lstSelectedLabel[lstSelectedLabel.Count - 1];
                dlgBrowse.SelectedLabel = selectedLabel;
                dlgBrowse.DoModal(GUIWindowManager.ActiveWindow);
                selectedLabel = dlgBrowse.SelectedLabel;
                lstSelectedLabel.RemoveAt(lstSelectedLabel.Count - 1);
                lstSelectedLabel.Add(selectedLabel);

                if (dlgBrowse.SelectedId < 0)
                    break;

                int selection = selectedLabel + (1 - firstItem);
                if (selection < 0)
                {
                    //exit
                    break;
                }

                else if (selection == 0)
                {
                    //previous folder
                    lstItems.RemoveAt(lstItems.Count - 1);
                    lstSelectedLabel.RemoveAt(lstSelectedLabel.Count - 1);
                }
                else
                {
                    ShellItem sItem = lstGuiItems[selection - 1];
                    if (!sItem.IsFolder)
                    {
                        path = sItem.Path;
                        break;
                    }
                    //open folder
                    lstItems.Add(sItem);
                    lstSelectedLabel.Add(0);
                }
            }

            return path;
        }

        public static string getGUIProperty(string which)
        {
            return MediaPortal.GUI.Library.GUIPropertyManager.GetProperty(which);
        }

        public static void setGUIProperty(string which, string value)
        {
            MediaPortal.GUI.Library.GUIPropertyManager.SetProperty(which, value);
        }

    }

    public class GUIListItemAlphabetSorter : IComparer<GUIListItem>
    {
        int IComparer<GUIListItem>.Compare( GUIListItem x, GUIListItem y)
        {
            return ((new CaseInsensitiveComparer()).Compare(x.Label, y.Label));
        }
    }
}
